home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / STARS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  8.4 KB  |  388 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /**
  5.  * (c) Copyright 1993, Silicon Graphics, Inc.
  6.  * ALL RIGHTS RESERVED 
  7.  * Permission to use, copy, modify, and distribute this software for 
  8.  * any purpose and without fee is hereby granted, provided that the above
  9.  * copyright notice appear in all copies and that both the copyright notice
  10.  * and this permission notice appear in supporting documentation, and that 
  11.  * the name of Silicon Graphics, Inc. not be used in advertising
  12.  * or publicity pertaining to distribution of the software without specific,
  13.  * written prior permission. 
  14.  *
  15.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  16.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  17.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  19.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  20.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  21.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  22.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  23.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  24.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  26.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  * 
  28.  * US Government Users Restricted Rights 
  29.  * Use, duplication, or disclosure by the Government is subject to
  30.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  31.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  32.  * clause at DFARS 252.227-7013 and/or in similar or successor
  33.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  34.  * Unpublished-- rights reserved under the copyright laws of the
  35.  * United States.  Contractor/manufacturer is Silicon Graphics,
  36.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  37.  *
  38.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  39.  */
  40.  
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <stdlib.h>
  44. #include <math.h>
  45. #include <time.h>
  46. #include <GL/glut.h>
  47.  
  48. extern void *__glutCurrentWindow;
  49.  
  50. /* Some <math.h> files do not define M_PI... */
  51. #ifndef M_PI
  52. #define M_PI 3.14159265358979323846
  53. #endif
  54.  
  55. enum {
  56.   NORMAL = 0,
  57.   WEIRD = 1
  58. };
  59.  
  60. enum {
  61.   STREAK = 0,
  62.   CIRCLE = 1
  63. };
  64.  
  65. #define MAXSTARS 400
  66. #define MAXPOS 10000
  67. #define MAXWARP 10
  68. #define MAXANGLES 6000
  69.  
  70. typedef struct _starRec {
  71.   GLint type;
  72.   float x[2], y[2], z[2];
  73.   float offsetX, offsetY, offsetR, rotation;
  74. } starRec;
  75.  
  76. GLenum doubleBuffer;
  77. GLint windW = 300, windH = 300;
  78.  
  79. GLenum flag = NORMAL;
  80. GLint starCount = MAXSTARS / 2;
  81. float speed = 1.0;
  82. GLint nitro = 0;
  83. starRec stars[MAXSTARS];
  84. float sinTable[MAXANGLES];
  85.  
  86. float
  87. Sin(float angle)
  88. {
  89.   return (sinTable[(int) angle % MAXANGLES]);
  90. }
  91.  
  92. float
  93. Cos(float angle)
  94. {
  95.   return (sinTable[((int) angle + (MAXANGLES / 4)) % MAXANGLES]);
  96. }
  97.  
  98. void
  99. NewStar(GLint n, GLint d)
  100. {
  101.   if (rand() % 4 == 0) {
  102.     stars[n].type = CIRCLE;
  103.   } else {
  104.     stars[n].type = STREAK;
  105.   }
  106.   stars[n].x[0] = (float) (rand() % MAXPOS - MAXPOS / 2);
  107.   stars[n].y[0] = (float) (rand() % MAXPOS - MAXPOS / 2);
  108.   stars[n].z[0] = (float) (rand() % MAXPOS + d);
  109.   stars[n].x[1] = stars[n].x[0];
  110.   stars[n].y[1] = stars[n].y[0];
  111.   stars[n].z[1] = stars[n].z[0];
  112.   if (rand() % 4 == 0 && flag == WEIRD) {
  113.     stars[n].offsetX = (float) (rand() % 100 - 100 / 2);
  114.     stars[n].offsetY = (float) (rand() % 100 - 100 / 2);
  115.     stars[n].offsetR = (float) (rand() % 25 - 25 / 2);
  116.   } else {
  117.     stars[n].offsetX = 0.0;
  118.     stars[n].offsetY = 0.0;
  119.     stars[n].offsetR = 0.0;
  120.   }
  121. }
  122.  
  123. void
  124. RotatePoint(float *x, float *y, float rotation)
  125. {
  126.   float tmpX, tmpY;
  127.  
  128.   tmpX = *x * Cos(rotation) - *y * Sin(rotation);
  129.   tmpY = *y * Cos(rotation) + *x * Sin(rotation);
  130.   *x = tmpX;
  131.   *y = tmpY;
  132. }
  133.  
  134. void
  135. MoveStars(void)
  136. {
  137.   float offset;
  138.   GLint n;
  139.  
  140.   offset = speed * 60.0;
  141.  
  142.   for (n = 0; n < starCount; n++) {
  143.     stars[n].x[1] = stars[n].x[0];
  144.     stars[n].y[1] = stars[n].y[0];
  145.     stars[n].z[1] = stars[n].z[0];
  146.     stars[n].x[0] += stars[n].offsetX;
  147.     stars[n].y[0] += stars[n].offsetY;
  148.     stars[n].z[0] -= offset;
  149.     stars[n].rotation += stars[n].offsetR;
  150.     if (stars[n].rotation >= MAXANGLES) {
  151.       stars[n].rotation = 0.0;
  152.     }
  153.   }
  154. }
  155.  
  156. GLenum
  157. StarPoint(GLint n)
  158. {
  159.   float x0, y0;
  160.  
  161.   x0 = stars[n].x[0] * windW / stars[n].z[0];
  162.   y0 = stars[n].y[0] * windH / stars[n].z[0];
  163.   RotatePoint(&x0, &y0, stars[n].rotation);
  164.   x0 += windW / 2.0;
  165.   y0 += windH / 2.0;
  166.  
  167.   if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
  168.     return GL_TRUE;
  169.   } else {
  170.     return GL_FALSE;
  171.   }
  172. }
  173.  
  174. void
  175. ShowStar(GLint n)
  176. {
  177.   float x0, y0, x1, y1, width;
  178.   GLint i;
  179.  
  180.   x0 = stars[n].x[0] * windW / stars[n].z[0];
  181.   y0 = stars[n].y[0] * windH / stars[n].z[0];
  182.   RotatePoint(&x0, &y0, stars[n].rotation);
  183.   x0 += windW / 2.0;
  184.   y0 += windH / 2.0;
  185.  
  186.   if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
  187.     if (stars[n].type == STREAK) {
  188.       x1 = stars[n].x[1] * windW / stars[n].z[1];
  189.       y1 = stars[n].y[1] * windH / stars[n].z[1];
  190.       RotatePoint(&x1, &y1, stars[n].rotation);
  191.       x1 += windW / 2.0;
  192.       y1 += windH / 2.0;
  193.  
  194.       glLineWidth(MAXPOS / 100.0 / stars[n].z[0] + 1.0);
  195.       glColor3f(1.0, (MAXWARP - speed) / MAXWARP, (MAXWARP - speed) / MAXWARP);
  196.       if (fabs(x0 - x1) < 1.0 && fabs(y0 - y1) < 1.0) {
  197.         glBegin(GL_POINTS);
  198.         glVertex2f(x0, y0);
  199.         glEnd();
  200.       } else {
  201.         glBegin(GL_LINES);
  202.         glVertex2f(x0, y0);
  203.         glVertex2f(x1, y1);
  204.         glEnd();
  205.       }
  206.     } else {
  207.       width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
  208.       glColor3f(1.0, 0.0, 0.0);
  209.       glBegin(GL_POLYGON);
  210.       for (i = 0; i < 8; i++) {
  211.         float x = x0 + width * Cos((float) i * MAXANGLES / 8.0);
  212.         float y = y0 + width * Sin((float) i * MAXANGLES / 8.0);
  213.         glVertex2f(x, y);
  214.       };
  215.       glEnd();
  216.     }
  217.   }
  218. }
  219.  
  220. void
  221. UpdateStars(void)
  222. {
  223.   GLint n;
  224.  
  225.   glClear(GL_COLOR_BUFFER_BIT);
  226.  
  227.   for (n = 0; n < starCount; n++) {
  228.     if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
  229.       if (StarPoint(n) == GL_FALSE) {
  230.         NewStar(n, MAXPOS);
  231.       }
  232.     } else {
  233.       NewStar(n, MAXPOS);
  234.     }
  235.   }
  236. }
  237.  
  238. void
  239. ShowStars(void)
  240. {
  241.   GLint n;
  242.  
  243.   glClear(GL_COLOR_BUFFER_BIT);
  244.  
  245.   for (n = 0; n < starCount; n++) {
  246.     if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
  247.       ShowStar(n);
  248.     }
  249.   }
  250. }
  251.  
  252. static void
  253. Init(void)
  254. {
  255.   float angle;
  256.   GLint n;
  257.  
  258.   srand((unsigned int) time(NULL));
  259.  
  260.   for (n = 0; n < MAXSTARS; n++) {
  261.     NewStar(n, 100);
  262.   }
  263.  
  264.   angle = 0.0;
  265.   for (n = 0; n < MAXANGLES; n++) {
  266.     sinTable[n] = sin(angle);
  267.     angle += M_PI / (MAXANGLES / 2.0);
  268.   }
  269.  
  270.   glClearColor(0.0, 0.0, 0.0, 0.0);
  271.  
  272.   glDisable(GL_DITHER);
  273. }
  274.  
  275. void
  276. Reshape(int width, int height)
  277. {
  278.   windW = width;
  279.   windH = height;
  280.  
  281.   glViewport(0, 0, windW, windH);
  282.  
  283.   glMatrixMode(GL_PROJECTION);
  284.   glLoadIdentity();
  285.   gluOrtho2D(-0.5, windW + 0.5, -0.5, windH + 0.5);
  286.   glMatrixMode(GL_MODELVIEW);
  287. }
  288.  
  289. /* ARGSUSED1 */
  290. static void
  291. Key(unsigned char key, int x, int y)
  292. {
  293.   switch (key) {
  294.   case ' ':
  295.     flag = (flag == NORMAL) ? WEIRD : NORMAL;
  296.     break;
  297.   case 't':
  298.     nitro = 1;
  299.     break;
  300.   case 27:
  301.     exit(0);
  302.   }
  303. }
  304.  
  305. void
  306. Idle(void)
  307. {
  308.   MoveStars();
  309.   UpdateStars();
  310.   if (nitro > 0) {
  311.     speed = (float) (nitro / 10) + 1.0;
  312.     if (speed > MAXWARP) {
  313.       speed = MAXWARP;
  314.     }
  315.     if (++nitro > MAXWARP * 10) {
  316.       nitro = -nitro;
  317.     }
  318.   } else if (nitro < 0) {
  319.     nitro++;
  320.     speed = (float) (-nitro / 10) + 1.0;
  321.     if (speed > MAXWARP) {
  322.       speed = MAXWARP;
  323.     }
  324.   }
  325.   glutPostRedisplay();
  326. }
  327.  
  328. void
  329. Display(void)
  330. {
  331.   ShowStars();
  332.   if (doubleBuffer) {
  333.     glutSwapBuffers();
  334.   } else {
  335.     glFlush();
  336.   }
  337. }
  338.  
  339. void
  340. Visible(int state)
  341. {
  342.   if (state == GLUT_VISIBLE) {
  343.     glutIdleFunc(Idle);
  344.   } else {
  345.     glutIdleFunc(NULL);
  346.   }
  347. }
  348.  
  349. static void
  350. Args(int argc, char **argv)
  351. {
  352.   GLint i;
  353.  
  354.   doubleBuffer = GL_TRUE;
  355.  
  356.   for (i = 1; i < argc; i++) {
  357.     if (strcmp(argv[i], "-sb") == 0) {
  358.       doubleBuffer = GL_FALSE;
  359.     } else if (strcmp(argv[i], "-db") == 0) {
  360.       doubleBuffer = GL_TRUE;
  361.     }
  362.   }
  363. }
  364.  
  365. int
  366. main(int argc, char **argv)
  367. {
  368.   GLenum type;
  369.  
  370.   glutInitWindowSize(windW, windH);
  371.   glutInit(&argc, argv);
  372.   Args(argc, argv);
  373.  
  374.   type = GLUT_RGB;
  375.   type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  376.   glutInitDisplayMode(type);
  377.   glutCreateWindow("Stars");
  378.  
  379.   Init();
  380.  
  381.   glutReshapeFunc(Reshape);
  382.   glutKeyboardFunc(Key);
  383.   glutVisibilityFunc(Visible);
  384.   glutDisplayFunc(Display);
  385.   glutMainLoop();
  386.   return 0;             /* ANSI C requires main to return int. */
  387. }
  388.